`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    01:28:33 03/17/2010 
// Design Name: 
// Module Name:    RAB_ctrl 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: Should SYNC signal be used here to?
//
//////////////////////////////////////////////////////////////////////////////////
module RAB_ctrl(    
	//Signals to/from the RAB
    output reg scanstart_n,
    output reg dac_sel,
    output reg control1,
    output reg control2,
    output reg dac_write_n,
    output reg dir,
    input wire [5:0] data_rab_in,
	output wire [5:0] data_rab_out,
	
	//input pixel timing clock signals
	input wire PS1,
    input wire PS2,
    input wire PS3,
	
	//SYNC signal from PFU notifying that a coupen has been inserted
	//input wire sync_n,
	
	//Signals to/from main system
	input wire clock,
	input wire reset,
    output [5:0] pixel,			//pixel value for actual reading
    output reg valid_pixel,		//goes HIGH when a valid pixel is in pixel port
	input [15:0] ctrl_data_in,		//new control value
	output reg [15:0] ctrl_data_out,
    input wire write_ctrl,			//write signal for control values
	input wire r_w_ctrl,			//selects reading or writing to control registers
    input wire [2:0] ctrl_word		//selects which control register to read or write:									
									//													000: DACA
									//													001: DACB
									//													010: SCANLENGTH
									//													100: EVEN_MEAN
									//													101: ODD_MEAN
    );	

localparam	DACA_VALUE = 6'b100101,// 37
			DACB_VALUE = 6'b100100,// 36 
			SCAN_LENGTH = 16'd1105,	//it can be modified
			FIRST_VALID_PIXEL = 16'd25;//first valid pixel is number 25 after a scanstart
			
			
reg [5:0] DACA_value;//DAC A register value holder
reg [5:0] DACB_value;//DAC B register value holder
reg [15:0] scanlength_reg;//Scan Length register: it holds the the length between scanlines
reg [5:0] even_mean;
reg [5:0] odd_mean;
reg [5:0] pix;
reg [15:0] even_acc;
reg [15:0] odd_acc;
reg [15:0] counter;
wire [15:0] counter_next;

reg write_dac, dac_sel_reg, init, enable_write, pixel_valid;
reg [2:0] aux;

wire [15:0] last_valid_pixel = FIRST_VALID_PIXEL + 16'd1024;//it shuold be 1049



//take pixel if valid, and signal to the outside that we have a valid pixel
always @(posedge PS1) begin
	if(pixel_valid) begin 
		pix <= data_rab_in; 
		valid_pixel <= 1'b1;
	end	
end

always @(posedge PS2) begin
	dac_write_n <= 1'b1;//drive dac_write_n pulse high, if it was driven low, it was on PS3 with counter == 0
	valid_pixel <= 1'b0;
end
//Counter Logic
assign counter_next = counter + 1; //next state logic

always @(posedge PS3) begin	
	counter = counter_next;				//add 1
	if(counter == scanlength_reg) counter = 0;//reset when scan line length reached	
end

`define DACA 1'b0
`define DACB 1'b1
`define ENABLE_N 1'b0
`define DISABLE_N 1'b1
`define DIR_INPUT 1'b0
`define DIR_OUTPUT 1'b1

//output logic for the RAB interface
//The value of the counter dictates the behavior, the change of the counter is synchronized with PS3 (see above)
always @(counter) begin
	//default values
	scanstart_n = `DISABLE_N;
	dac_sel = dac_sel_reg;
	dac_write_n = `DISABLE_N;
	dir = `DIR_INPUT;
	control1 = 1'b1;
	control2 = 1'b1;
	pixel_valid = 1'b0;
	
	if(counter == 0) begin //when counter is Zero the scanlength has been reached, so a new scan has to be initiated
		scanstart_n = `ENABLE_N;//enable the scanstart line
		dir = `DIR_OUTPUT;		//direction is output in this interval	

		if(enable_write) dac_write_n = `ENABLE_N; //if a DAC needs to be write, we drive low dac_write_n line (it will be drive high automatically on next PS2)
												  //the values are already on the data_bus for the RAB
												  
												  
	end
	
	//control1 and control2 logic
	if( (16'd12 <= counter) && (counter < 16'd14) ) control1 = 1'b0;
	if( (16'd13 <= counter) && (counter < 16'd15) ) control2 = 1'b0;
	
	if((FIRST_VALID_PIXEL <= counter) && (counter <= last_valid_pixel)) pixel_valid = 1'b1;
	
end	
		

always @(posedge reset)
	if(reset) begin
		DACA_value <= DACA_VALUE;
		DACB_value <= DACB_VALUE;
		scanlength_reg <= SCAN_LENGTH;
		init <= 1'b1;
		dac_sel_reg <= `DACB;
		pixel_valid <= 0;
		aux <= 2'b0;
		valid_pixel <= 1'b0;
		
	end
/*	else
		if(init) begin*/
			

//output data bus with enable, because it is a shared data bus
assign data_rab_out =	(dir & dac_sel) ? DACB_value :
					(dir & ~dac_sel)? DACA_value :
					6'bz;

assign pixel = pix;
			
endmodule
